#pragma once

#include <dlib/dnn.h>
#include <dlib/image_processing/frontal_face_detector.h>
#include <dlib/image_processing.h>
#include <dlib/image_io.h>
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
#include "ConfigParser.h"

// 使用dlib官方示例中的网络定义
template <template <int, template <typename> class, int, typename> class block, int N, template <typename> class BN, typename SUBNET>
using residual = dlib::add_prev1<block<N, BN, 1, dlib::tag1<SUBNET>>>;

template <template <int, template <typename> class, int, typename> class block, int N, template <typename> class BN, typename SUBNET>
using residual_down = dlib::add_prev2<dlib::avg_pool<2, 2, 2, 2, dlib::skip1<dlib::tag2<block<N, BN, 2, dlib::tag1<SUBNET>>>>>>;

template <int N, template <typename> class BN, int stride, typename SUBNET>
using block = BN<dlib::con<N, 3, 3, 1, 1, dlib::relu<BN<dlib::con<N, 3, 3, stride, stride, SUBNET>>>>>;

template <int N, typename SUBNET> using ares = dlib::relu<residual<block, N, dlib::affine, SUBNET>>;
template <int N, typename SUBNET> using ares_down = dlib::relu<residual_down<block, N, dlib::affine, SUBNET>>;

template <typename SUBNET> using alevel0 = ares_down<256, SUBNET>;
template <typename SUBNET> using alevel1 = ares<256, ares<256, ares_down<256, SUBNET>>>;
template <typename SUBNET> using alevel2 = ares<128, ares<128, ares_down<128, SUBNET>>>;
template <typename SUBNET> using alevel3 = ares<64, ares<64, ares<64, ares_down<64, SUBNET>>>>;
template <typename SUBNET> using alevel4 = ares<32, ares<32, ares<32, SUBNET>>>;

// 定义深度神经网络模型类型
using anet_type = dlib::loss_metric<dlib::fc_no_bias<128, dlib::avg_pool_everything<
    alevel0<
    alevel1<
    alevel2<
    alevel3<
    alevel4<
    dlib::max_pool<3, 3, 2, 2, dlib::relu<dlib::affine<dlib::con<32, 7, 7, 2, 2,
    dlib::input_rgb_image_sized<150>
    >>>>>>>>>>>>;

class FaceRecognizer {
public:
    // 构造函数：加载配置和模型
    FaceRecognizer(ConfigParser& config);
    
    // 打印人脸库信息
    void printFaceLibInfo() const;
    
    // 人脸匹配：输入人脸图像，返回身份
    std::string recognizeFace(const dlib::matrix<dlib::rgb_pixel>& face_chip);
    
    // 人脸检测：输入图像，返回人脸位置
    std::vector<dlib::rectangle> detectFaces(const dlib::matrix<dlib::rgb_pixel>& img);
    
    // 对齐人脸：输入图像和人脸位置，返回对齐后的人脸
    dlib::matrix<dlib::rgb_pixel> alignFace(
        const dlib::matrix<dlib::rgb_pixel>& img, 
        const dlib::rectangle& face_rect);

private:
    // 人脸数据库条目结构
    struct FaceRecord {
        std::string name;
        dlib::matrix<float,0,1> descriptor;
    };
    
    // 加载人脸库
    bool loadFaceLib();
    
    // 人脸识别阈值
    double threshold_;
    
    // 人脸库
    std::vector<FaceRecord> face_lib_;
    
    // 模型路径
    std::string shape_model_path_;
    std::string resnet_model_path_;
    std::string face_lib_path_;
    
    // 模型对象
    dlib::frontal_face_detector detector_;
    dlib::shape_predictor sp_;
    anet_type net_;
};